/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kaindorfcompany.webshop.productmanagement.backend.access;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import kaindorfcompany.webshop.productmanagement.backend.exceptions.NoConnectionAvailableException;

/**
 *
 * @author Thomas Jahoda
 */
public class DbAdvancedConnectionPool {

    private static final DbConnectionConfigProfile DB_PROFILE = DbConnectionConfigProfile.REMOTE_MAIN_MYSQL_DB;
    private DbConnectionConfig connectionConfig;
    private final int MAX_CONNECTIONS = 150;
    private int numberCreatedConnections;
    private LinkedList<AdvancedConnection> connections;
    private static DbAdvancedConnectionPool instance;

    private DbAdvancedConnectionPool(DbConnectionConfig connectionConfig) throws ClassNotFoundException {
        this.connectionConfig = connectionConfig;
        connections = new LinkedList<AdvancedConnection>();
        numberCreatedConnections = 0;
        Class.forName(connectionConfig.getDbDriver());
    }

    public static DbAdvancedConnectionPool getInstance() throws ClassNotFoundException {
        if (instance == null) {
            synchronized (DbAdvancedConnectionPool.class) {
                if (instance == null) {
                    instance = new DbAdvancedConnectionPool(DB_PROFILE);
                }
            }
        }
        return instance;
    }

    public synchronized AdvancedConnection getConnection() throws NoConnectionAvailableException, SQLException {
        if (connections.isEmpty()) {
            if (numberCreatedConnections < MAX_CONNECTIONS) {
                numberCreatedConnections++;
                String dbUrl = connectionConfig.getDbUrl();
                String dbName = connectionConfig.getDbName();
                String dbUser = connectionConfig.getDbUser();
                String dbPassword = connectionConfig.getDbPassword();
                return new AdvancedConnection(DriverManager.getConnection(dbUrl + dbName, dbUser, dbPassword));
            } else {
                throw new NoConnectionAvailableException("There is no database connection available at the moment.");
            }
        } else {
            return connections.poll();
        }
    }

    public synchronized void releaseConnection(AdvancedConnection ac) {
        if (ac == null) {
            throw new NullPointerException();
        }
        connections.offer(ac);
    }
}
